/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.futuremind.recyclerviewfastscroll.viewprovider;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.components.Component;

/**
 * AttrValue
 *
 * @since 2021-03-26
 */
public class VisibilityAnimationManager {
    /**
     * Component变量
     */
    protected Component view;
    /**
     * AnimatorProperty隐藏变量
     */
    protected AnimatorProperty hideAnimator;
    /**
     * AnimatorProperty变量
     */
    protected AnimatorProperty showAnimator;
    private float pivotXelative;
    private float pivotYelative;

    /**
     * VisibilityAnimationManager
     *
     * @param view           视图
     * @param animationUntil 实体类
     */
    protected VisibilityAnimationManager(final Component view, AnimationUntil animationUntil) {
        this.view = view;
        this.pivotXelative = animationUntil.getPivotXelative(); // pivotXelative;
        this.pivotYelative = animationUntil.getPivotYelative(); // pivotYelative;
        this.hideAnimator = animationUntil.getHideAnimator(); // hideAnimator;
        this.hideAnimator.setDelay(animationUntil.getHideDelay()); // hideDelay
        this.hideAnimator.setTarget(view);
        this.showAnimator = animationUntil.getShowAnimator(); // showAnimator;
        this.showAnimator.setTarget(view);
        stateChange();
        updatePivot();
    }

    /**
     * stateChange
     */
    private void stateChange() {
        this.hideAnimator.setStateChangedListener(new Animator.StateChangedListener() {
            boolean isWasCanceled;

            @Override
            public void onStart(Animator animator) {
            }

            @Override
            public void onStop(Animator animator) {
                isWasCanceled = false;
            }

            @Override
            public void onCancel(Animator animator) {
                isWasCanceled = true;
            }

            @Override
            public void onEnd(Animator animator) {
                if (!isWasCanceled) {
                    view.setVisibility(Component.INVISIBLE);
                }
                isWasCanceled = false;
            }

            @Override
            public void onPause(Animator animator) {
            }

            @Override
            public void onResume(Animator animator) {
            }
        });
    }

    /**
     * show
     */
    public void show() {
        hideAnimator.cancel();

        if (view.getVisibility() == Component.INVISIBLE) {
            view.setVisibility(Component.VISIBLE);
            updatePivot();
            showAnimator.start();
        }
    }

    /**
     * hide
     */
    public void hide() {
        updatePivot();
        hideAnimator.start();
    }

    /**
     * updatePivot
     */
    protected void updatePivot() {
        view.setPivotX(pivotXelative * view.getWidth());
        view.setPivotY(pivotYelative * view.getHeight());
    }

    /**
     * abstract
     *
     * @param <T>
     * @since 2021-03-26
     */
    public abstract static class AbsBuilder<T extends VisibilityAnimationManager> {
        /**
         * 声明变量 Component
         */
        protected Component view;
        /**
         * 声明变量AnimatorProperty
         */
        protected AnimatorProperty showAnimator;
        /**
         * 声明变量AnimatorProperty
         */
        protected AnimatorProperty hideAnimator;
        /**
         * 声明变量hideDelay
         */
        protected int hideDelay = 1000;
        /**
         * 声明变量pivotX
         */
        protected float pivotX = 0.5f;
        /**
         * 声明变量pivotY
         */
        protected float pivotY = 0.5f;

        /**
         * AbsBuilder
         *
         * @param view q
         */
        public AbsBuilder(Component view) {
            this.view = view;
            initDefaultAnimator();
        }

        /**
         * AbsBuilder
         *
         * @param showAnimatorResource q
         * @return AbsBuilder
         */
        public AbsBuilder<T> withShowAnimator(AnimatorProperty showAnimatorResource) {
            this.showAnimator = showAnimatorResource;
            return this;
        }

        /**
         * AbsBuilder
         *
         * @param hideAnimatorResource q
         * @return AbsBuilder
         */
        public AbsBuilder<T> withHideAnimator(AnimatorProperty hideAnimatorResource) {
            this.hideAnimator = hideAnimatorResource;
            return this;
        }

        /**
         * AbsBuilder
         *
         * @param hiDe q
         * @return AbsBuilder
         */
        public AbsBuilder<T> withHideDelay(int hiDe) {
            this.hideDelay = hiDe;
            return this;
        }

        /**
         * AbsBuilder
         *
         * @param pivotx q
         * @return AbsBuilder
         */
        public AbsBuilder<T> withPivotX(float pivotx) {
            this.pivotX = pivotx;
            return this;
        }

        /**
         * AbsBuilder
         *
         * @param pivoty q
         * @return 1
         */
        public AbsBuilder<T> withPivotY(float pivoty) {
            this.pivotY = pivoty;
            return this;
        }

        /**
         * initDefaultAnimator
         */
        public void initDefaultAnimator() {
            final long at = 200L;
            showAnimator = new AnimatorProperty()
                    .scaleX(1).scaleY(1).alpha(1).setDuration(at)
                    .setCurveType(Animator.CurveType.ACCELERATE);
            hideAnimator = new AnimatorProperty()
                    .scaleX(0).scaleY(0).alpha(0).setDuration(at)
                    .setCurveType(Animator.CurveType.ACCELERATE);
        }

        /**
         * abstract
         *
         * @return t
         */
        public abstract T build();
    }

    /**
     * Builder
     *
     * @since 2021-03-26
     */
    public static class Builder extends AbsBuilder<VisibilityAnimationManager> {
        /**
         * Builder
         *
         * @param view 1
         */
        public Builder(Component view) {
            super(view);
        }

        /**
         * VisibilityAnimationManager
         *
         * @return 1
         */
        public VisibilityAnimationManager build() {
            AnimationUntil animation = new AnimationUntil();
            animation.setShowAnimator(showAnimator);
            animation.setHideAnimator(hideAnimator);
            animation.setPivotXelative(pivotX);
            animation.setPivotYelative(pivotY);
            animation.setHideDelay(hideDelay);
            return new VisibilityAnimationManager(view, animation);
        }
    }
}
